﻿using _RobotInspection.DTO;
using _RobotInspection.Entities;
using _RobotInspection.Interfaces;
using _RobotInspection.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using RobotInspection.Entities;
using SqlSugar;
using System.DirectoryServices.Protocols;

namespace _RobotInspection.Services
{
    /// <summary>
    /// 设备相关功能服务层实现类
    /// </summary>
    public class EquipmentService:IEquipmentService
    {
        private readonly ISqlSugarClient _db;
        private readonly ILogger<EquipmentService> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="db"></param>
        /// <param name="logger"></param>
        public EquipmentService(ISqlSugarClient db, ILogger<EquipmentService> logger)
        {
            _db = db;
            _logger = logger;
        }

        /// <summary>
        /// 异步分页查询设备
        /// </summary>
        /// <returns></returns>
        public async Task<ApiResponse<EquipmentPagedResultDto>> GetEquipmentsPagedAsync(EquipmentPagedQueryDto queryDto)
        {
            // 执行数据查询
            try
            { 
                var queryable = _db.Queryable<equipment>()
                    .LeftJoin<equipment_user_relations>((e, eu) => e.id == eu.equipment_id)
                    .LeftJoin<users>((e, eu, u) => eu.user_id == u.id);

                // 按要求添加查询条件
                if (!string.IsNullOrWhiteSpace(queryDto.CompanyName))
                {
                    queryable = queryable.Where((e, eu, u) => e.company_name.Contains(queryDto.CompanyName));
                }
                if (!string.IsNullOrWhiteSpace(queryDto.Unit))
                {
                    queryable = queryable.Where((e, eu, u) => e.unit.Contains(queryDto.Unit));
                }
                if (queryDto.UserId.HasValue)
                {
                    queryable = queryable.Where((e, eu, u) => u.id == queryDto.UserId);
                }
                if (!string.IsNullOrWhiteSpace(queryDto.EquipmentName))
                {
                    queryable = queryable.Where((e, eu, u) => e.equipment_name.Contains(queryDto.EquipmentName));
                }

                // 获取总记录数
                var totalCount = await queryable.CountAsync();

                // 准备返回数据
                var equipmentResultDtoList = await queryable.Select((e, eu, u) => new EquipmentResultDto
                {
                    EquipmentId = e.id,
                    EquipmentName = e.equipment_name,
                    RealName = u.real_name,
                    CompanyName = e.company_name,
                    Unit = e.unit,
                    EquipmentCode = e.equipment_code,
                    BaoRobotNumber = e.bao_robot_number,
                    EquipmentType = e.equipment_type,
                    Location = e.location,
                    Manufacturer = e.manufacturer,
                    Model = e.model,
                    Status = e.status ?? 0,
                    DeviceDescrption = e.device_description
                }).ToPageListAsync(queryDto.PageIndex, queryDto.PageSize);

                //判断总页数
                var totalPages = 0;
                if (totalCount % queryDto.PageSize > 0)
                {
                    totalPages = totalCount / queryDto.PageSize + 1;
                }
                else
                {
                    totalPages = totalCount / queryDto.PageSize;
                }

                //准备返回数据
                var equipmentPagedResultDto = new EquipmentPagedResultDto
                {
                    EquipmentResultList = equipmentResultDtoList,
                    TotalCount = totalCount,
                    TotalPages = totalPages,
                    CurrentPage = queryDto.PageIndex,
                    PageSize = queryDto.PageSize,
                    HasPreviousPage = queryDto.PageIndex > 1,
                    HasNextPage = queryDto.PageIndex < totalPages
                };

                var message = $"查询到设备总数：{totalCount}";

                return ApiResponse<EquipmentPagedResultDto>.Success(equipmentPagedResultDto, message, totalCount);
            }
            catch (Exception ex)
            {
                return ApiResponse<EquipmentPagedResultDto>.Error($"查询失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步按照Id查询设备
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ApiResponse<equipment>> GetEquipmentByIdAsync(long id)
        {
            if (id <= 0)
            {
                return ApiResponse<equipment>.Error("查询失败：设备ID无效",400);
            }

            try
            {
                var equipmentList = await _db.Queryable<equipment>().Where(i => i.id == id).ToListAsync();
                if (equipmentList.Count == 1)
                {
                    return ApiResponse<equipment>.Success(equipmentList[0], null);
                }
                else
                {
                    return ApiResponse<equipment>.Error("查询失败：设备不存在", 400);
                }
            }
            catch (Exception ex)
            {
                return ApiResponse<equipment>.Error($"查询失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步按设备Id查询设备资料
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ApiResponse<List<equipment_resource>>> GetEquipmentResourceByEquipmentIdAsync(long id)
        {
            if (id <= 0)
            {
                return ApiResponse<List<equipment_resource>>.Error($"设备资料查询失败：设备ID不合法", 400);
            }

            try
            {
                var equipmentList = await _db.Queryable<equipment>().Where(e => e.id == id).ToListAsync();
                if (equipmentList.Count != 1)
                {
                    return ApiResponse<List<equipment_resource>>.Error($"设备资料查询失败：设备ID不存在或错误", 400);
                }

                var equipmentResourceList = await _db.Queryable<equipment_resource>().Where(e => e.equipment_id == id).ToListAsync();
                return ApiResponse<List<equipment_resource>>.Success(equipmentResourceList, null);
            }
            catch (Exception ex)
            {
                return ApiResponse<List<equipment_resource>>.Error($"设备资料查询失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步按Id查询设备资料
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ApiResponse<equipment_resource>> GetEquipmentResourceByIdAsync(long id)
        {
            if (id <= 0)
            {
                return ApiResponse<equipment_resource>.Error($"设备资料查询失败：设备ID不合法", 400);
            }
            try
            {
                var equipmentResourceList = await _db.Queryable<equipment_resource>().Where(er => er.id == id).ToListAsync();
                if (equipmentResourceList.Count != 1)
                {
                    return ApiResponse<equipment_resource>.Error($"设备资料查询失败：设备ID不存在或错误", 400);
                }

                return ApiResponse<equipment_resource>.Success(equipmentResourceList[0], null);
            }
            catch (Exception ex)
            {
                return ApiResponse<equipment_resource>.Error($"设备资料查询失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步创建设备
        /// </summary>
        /// <param name="queryDto"></param>
        /// <returns></returns>
        public async Task<ApiResponse<object>> InsertEquipmentAsync(EquipmentInsertDto queryDto)
        {
            if (string.IsNullOrWhiteSpace(queryDto.EquipmentName))
            {
                return ApiResponse<object>.Error($"设备创建失败：需要设备名称", 400);
            }
            if (!queryDto.UserId.HasValue)
            {
                return ApiResponse<object>.Error($"设备创建失败：需要负责人", 400);
            }
            if (queryDto.UserId <= 0)
            {
                return ApiResponse<object>.Error($"设备创建失败：用户ID不合法", 400);
            }

            try
            {
                // 校验设备编码是否重复
                var equipmentNumber = await _db.Queryable<equipment>().Where(e => e.equipment_code == queryDto.EquipmentCode).CountAsync();
                if(equipmentNumber > 0)
                {
                    return ApiResponse<object>.Error($"设备创建失败：设备编码重复", 400);
                }

                // 如果指定负责人，校验负责人是否存在
                if (queryDto.UserId.HasValue)
                {
                    var userNumber = await _db.Queryable<users>().Where(u => u.id == queryDto.UserId).CountAsync();
                    if (userNumber == 0) 
                    {
                        return ApiResponse<object>.Error($"设备创建失败：负责人ID不存在", 400);
                    }
                }

                //准备设备数据
                var equipment = new equipment
                {
                    company_name = queryDto.CompanyName ?? "NeedCompanyName",
                    unit = queryDto.Unit ?? "NeedUnit",
                    equipment_name = queryDto.EquipmentName ?? "ErrorEquipmentName",
                    equipment_code = queryDto.EquipmentCode ?? "NeedEquipmentCode",
                    bao_robot_number = queryDto.BaoRobotNumber ?? "NeedBaoRobotNumber",
                    equipment_type = queryDto.EquipmentType ?? "NeedEquipmentType",
                    location = queryDto.Location ?? "NeedLocation",
                    manufacturer = queryDto.Manufacturer ?? "NeedManufacturer",
                    model = queryDto.Model ?? "NeedModel",
                    status = queryDto.Status ?? 1,
                    device_description = queryDto.DeviceDescrption ?? "NeedDeviceDescrption",
                    created_at = DateTime.Now,
                    updated_at = DateTime.Now
                };

                // 插入设备数据
                var equipmentResult = await _db.Insertable(equipment).ExecuteReturnEntityAsync();

                // 查询设备的id
                var equipmentId = await _db.Queryable<equipment>().Where(e => e.id == equipmentResult.id).Select(e => e.id).FirstAsync();
                
                // 准备设备-用户关联项数据
                var equipmentUser = new equipment_user_relations
                {
                    equipment_id = equipmentId,
                    user_id = queryDto.UserId ?? 0,
                    is_primary = 1,
                    is_active = 1,
                    remark = "",
                    created_at = DateTime.Now,
                    updated_at = DateTime.Now
                };

                // 插入数据
                var equipmentUserResult = await _db.Insertable(equipmentUser).ExecuteReturnEntityAsync();

                //准备返回数据结构
                var result = new
                {
                    EquipmentResult = equipmentResult,
                    EquipmentUserResult = equipmentUserResult
                };

                return ApiResponse<object>.Success(result, "设备创建成功");
            }
            catch (Exception ex)
            {
                return ApiResponse<object>.Error($"设备创建失败：{ex.Message}", 500);
            }
        }
        
        /// <summary>
        /// 异步创建设备资料
        /// </summary>
        /// <param name="queryDto"></param>
        /// <returns></returns>
        public async Task<ApiResponse<equipment_resource>> InsertEquipmentResourceAsync(EquipmentResourceDto queryDto)
        {
            if (queryDto.EquipmentId <= 0)
            {
                return ApiResponse<equipment_resource>.Error($"设备资料创建失败：设备ID不合法", 400);
            }

            try
            {
                var equipmentList = await _db.Queryable<equipment>().Where(e => e.id == queryDto.EquipmentId).ToListAsync();
                if (equipmentList.Count != 1)
                {
                    return ApiResponse<equipment_resource>.Error($"设备资料创建失败：设备ID不存在或错误", 400);
                }
                if (queryDto.ResourceFile.Length == 0) 
                {
                    return ApiResponse<equipment_resource>.Error($"设备资料创建失败：未上传文件", 400);
                }

                // 保存文件的准备工作
                string saveDir = Path.Combine(Directory.GetCurrentDirectory(), "EquipmentResource");
                if (!Directory.Exists(saveDir))
                {
                    Directory.CreateDirectory(saveDir);
                }
                string fileName = $"{Guid.NewGuid()}_{Path.GetFileName(queryDto.ResourceFile.FileName)}";
                string savePath = Path.Combine(saveDir, fileName);

                // 保存文件
                using (var stream = new FileStream(savePath, FileMode.Create))
                {
                    await queryDto.ResourceFile.CopyToAsync(stream);
                }

                // 创建设备资料数据
                var equipmentResource = new equipment_resource
                {
                    equipment_id = queryDto.EquipmentId,
                    resource_name = queryDto.ResourceName,
                    resource_type = queryDto.ResourceType,
                    resource_path = savePath,
                    uploader = queryDto.Uploader,
                    uploaded_at = DateTime.Now
                };

                // 插入数据
                var equipmentResourceResult = await _db.Insertable(equipmentResource).ExecuteReturnEntityAsync();
                return ApiResponse<equipment_resource>.Success(equipmentResourceResult, "设备资料创建成功");
            }
            catch (Exception ex)
            {
                return ApiResponse<equipment_resource>.Error($"设备资料创建失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步修改设备
        /// </summary>
        /// <param name="queryDto"></param>
        /// <returns></returns>
        public async Task<ApiResponse<object>> UpdateEquipmentAsync(EquipmentUpdateDto queryDto)
        {
            // 检验id是否合法
            if (queryDto.Id <= 0 && queryDto.UserId <= 0)
            {
                return ApiResponse<object>.Error("设备修改失败：设备ID不合法", 400);
            }
            if (queryDto.UserId.HasValue)
            {
                if(queryDto.UserId <= 0)
                {
                    return ApiResponse<object>.Error("设备修改失败：负责人ID不合法", 400);
                }
            }

            try
            {
                // 检验设备是否存在
                var equipmentList = await _db.Queryable<equipment>().Where(i => i.id == queryDto.Id).ToListAsync();
                if (equipmentList.Count != 1)
                {
                    return ApiResponse<object>.Error("设备修改失败：设备ID不存在或错误", 400);
                }

                // 检验用户是否存在
                var userList = new List<users> { };
                if (queryDto.UserId.HasValue)
                {
                    userList = await _db.Queryable<users>().Where(i => i.id == queryDto.UserId).ToListAsync();
                    if (userList.Count != 1)
                    {
                        return ApiResponse<object>.Error("设备修改失败：负责人ID不存在或错误", 400);
                    }
                }
                
                var equipmentUserResult = new equipment_user_relations { };
                // 判断是否需要创建或修改设备-用户关联表
                if (queryDto.UserId.HasValue)
                {
                    // 检验设备是否绑定负责人
                    var equipmentUser = await _db.Queryable<equipment_user_relations>().Where(eu => eu.equipment_id == queryDto.Id).ToListAsync();
                    if (equipmentUser.Count == 1)// 设备绑定了负责人
                    {
                        var equipmentUserUpdate = new equipment_user_relations
                        {
                            id = equipmentUser[0].id,
                            equipment_id = queryDto.Id,
                            user_id = queryDto.UserId ?? 0,
                            is_primary = equipmentUser[0].is_active,
                            is_active = equipmentUser[0].is_active,
                            remark = equipmentUser[0].remark,
                            created_at = equipmentUser[0].created_at,
                            updated_at = DateTime.Now
                        };
                        equipmentUserResult = await _db.Updateable(equipmentUserUpdate).ExecuteReturnEntityAsync();
                    }
                    else //设备未绑定负责人
                    {
                        var equipmentUserInsert = new equipment_user_relations
                        {
                            equipment_id = queryDto.Id,
                            user_id = queryDto.UserId ?? 0,
                            is_primary = 0,
                            is_active = 1,
                            remark = "",
                            created_at = DateTime.Now,
                            updated_at = DateTime.Now
                        };
                        equipmentUserResult = await _db.Insertable(equipmentUserInsert).ExecuteReturnEntityAsync();
                    }

                }
                
                //创建设备数据结构
                var equipementUpdate = new equipment
                {
                    id = queryDto.Id,
                    company_name = queryDto.CompanyName ?? equipmentList[0].company_name,
                    unit = queryDto.Unit ?? equipmentList[0].unit,
                    equipment_name = queryDto.EquipmentName ?? equipmentList[0].equipment_name,
                    equipment_code = queryDto.EquipmentCode ?? equipmentList[0].equipment_code,
                    bao_robot_number = queryDto.BaoRobotNumber ?? equipmentList[0].bao_robot_number,
                    equipment_type = queryDto.EquipmentType ?? equipmentList[0].equipment_type,
                    location = queryDto.Location ?? equipmentList[0].location,
                    manufacturer = queryDto.Manufacturer ?? equipmentList[0].manufacturer,
                    model = queryDto.Model ?? equipmentList[0].model,
                    status = queryDto.Status ?? equipmentList[0].status,
                    device_description = queryDto.DeviceDescrption ?? equipmentList[0].device_description,
                    created_at = equipmentList[0].created_at,
                    updated_at = DateTime.Now

                };
                var equipmentResult = await _db.Updateable(equipementUpdate).ExecuteReturnEntityAsync();

                var result = new 
                {
                    EquipmentResult = equipmentResult,
                    EquipmentUserResult = equipmentUserResult

                };

                return ApiResponse<object>.Success(result, "设备及其关联表修改成功");

            }
            catch (Exception ex)
            {
                return ApiResponse<object>.Error($"设备修改失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步删除设备
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="BusinessException"></exception>
        public async Task<ApiResponse<equipment?>> DeleteEquipmentAsync(long id)
        {
            // 检验id是否合法
            if (id <= 0) 
            {
                return ApiResponse<equipment?>.Error("查询失败：设备ID不合法", 400);
            }

            try
            {
                // 检验设备是否存在
                var equipmentNumber = await _db.Queryable<equipment>().Where(i => i.id == id).CountAsync();
                if (equipmentNumber == 0)
                {
                    return ApiResponse<equipment?>.Error("设备删除失败：设备id不存在或错误", 400);
                }

                // 检验并删除设备-用户关联项
                var euNumber = await _db.Queryable<equipment_user_relations>().Where(eu => eu.equipment_id == id).CountAsync();
                if (euNumber > 0)
                {
                    await _db.Deleteable<equipment_user_relations>().Where(eu => eu.equipment_id == id).ExecuteCommandAsync();
                }

                // 检验并删除设备关联的点检项目
                var iNumber = await _db.Queryable<inspection_items>().Where(i => i.equipment_id == id).CountAsync();
                if (iNumber > 0) 
                { 
                    await _db.Deleteable<inspection_items>().Where(i => i.equipment_id == id).ExecuteCommandAsync(); 
                }

                //检验并删除设备资料关联项
                var equipmentResourceList = await _db.Queryable<equipment_resource>().Where(er => er.equipment_id == id).ToListAsync();
                if (equipmentResourceList.Count > 0)
                {
                    foreach (var equipmentResource in equipmentResourceList)
                    {
                        if (File.Exists(equipmentResource.resource_path))
                        {
                            File.Delete(equipmentResource.resource_path);
                        }
                        await _db.Deleteable<equipment_resource>().Where(er => er.id == equipmentResource.id).ExecuteCommandAsync();
                    }
                }

                // 删除设备
                await _db.Deleteable<equipment>().Where(i => i.id == id).ExecuteCommandAsync();

                // 总结上述操作
                string message = $"删除设备-用户关联项{euNumber}个，删除设备关联的点检项目{iNumber}个，删除设备关联的资料{equipmentResourceList.Count}个，设备删除成功";

                return ApiResponse<equipment?>.Success(null, message);

            }
            catch (Exception ex)
            {
                return ApiResponse<equipment?>.Error($"设备删除失败：{ex.Message}", 500);
            }
        }

        /// <summary>
        /// 异步批量删除设备
        /// </summary>
        /// <param name="idList"></param>
        /// <returns></returns>
        public async Task<ApiResponse<List<string>>> DeleteEquipmentListAsync(List<long> idList)
        {
            List<string> messageList = [];
            foreach(var id in idList)
            {
                // 检验id是否合法
                if (id <= 0)
                {
                    return ApiResponse<List<string>>.Error($"设备批量删除失败：设备{id}ID不合法", 400);
                }

                try
                {
                    // 检验设备是否存在
                    var equipmentNumber = await _db.Queryable<equipment>().Where(i => i.id == id).CountAsync();
                    if (equipmentNumber == 0)
                    {
                        return ApiResponse<List<string>>.Error($"设备批量删除失败：设备{id}id不存在或错误", 400);
                    }

                    // 检验并删除设备-用户关联项
                    var euNumber = await _db.Queryable<equipment_user_relations>().Where(eu => eu.equipment_id == id).CountAsync();
                    if (euNumber > 0)
                    {
                        await _db.Deleteable<equipment_user_relations>().Where(eu => eu.equipment_id == id).ExecuteCommandAsync();
                    }

                    // 检验并删除设备关联的点检项目
                    var iNumber = await _db.Queryable<inspection_items>().Where(i => i.equipment_id == id).CountAsync();
                    if (iNumber > 0)
                    {
                        await _db.Deleteable<inspection_items>().Where(i => i.equipment_id == id).ExecuteCommandAsync();
                    }

                    //检验并删除设备资料关联项
                    var equipmentResourceList = await _db.Queryable<equipment_resource>().Where(er => er.equipment_id == id).ToListAsync();
                    if (equipmentResourceList.Count > 0)
                    {
                        foreach (var equipmentResource in equipmentResourceList)
                        {
                            if (File.Exists(equipmentResource.resource_path))
                            {
                                File.Delete(equipmentResource.resource_path);
                            }
                            await _db.Deleteable<equipment_resource>().Where(er => er.id == equipmentResource.id).ExecuteCommandAsync();
                        }
                    }

                    // 删除设备
                    await _db.Deleteable<equipment>().Where(i => i.id == id).ExecuteCommandAsync();

                    // 总结上述操作
                    string message = $"删除设备-用户关联项{euNumber}个，删除设备关联的点检项目{iNumber}个，删除设备关联的资料{equipmentResourceList.Count}个，设备{id}删除成功";
                    messageList.Add(message);
                }
                catch (Exception ex)
                {
                    return ApiResponse<List<string>>.Error($"设备{id}批量删除失败：{ex.Message}", 500);
                }
            }
            return ApiResponse<List<string>>.Success(messageList,$"{idList.Count}个设备批量删除成功");
        }

        /// <summary>
        /// 异步删除设备资料
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ApiResponse<equipment_resource?>> DeleteEquipmentResourceAsync(long id)
        {
            if (id <= 0)
            {
                return ApiResponse<equipment_resource?>.Error("设备资料删除失败：设备资料ID不合法", 400);
            }

            try
            {
                var equipmentResourceList = await _db.Queryable<equipment_resource>().Where(er => er.id == id).ToListAsync();
                if (equipmentResourceList.Count != 0) 
                {
                    return ApiResponse<equipment_resource?>.Error("设备资料删除失败：设备资料不存在", 400);
                }

                // 删除本地文件
                if (File.Exists(equipmentResourceList[0].resource_path))
                {
                    File.Delete(equipmentResourceList[0].resource_path);
                }
                
                // 删除数据库记录
                await _db.Deleteable<equipment_resource>().Where(i => i.id == id).ExecuteCommandAsync();

                return ApiResponse<equipment_resource?>.Success(null, "设备资料删除成功");
            }
            catch (Exception ex)
            {
                return ApiResponse<equipment_resource?>.Error($"设备资料删除失败：{ex.Message}", 500);
            }
        }

        
    }
}
